package com.atguigu.day72_demo;

/**
 * 老版 synchronized + wait + notifyAll
 */

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 新版JUC写法  Lock + condition.await() + condition.signalAll()
 */
class AirCondition {
    private int number = 0;
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();

    public void add() {
        lock.lock();
        try {
            while (number != 0) {
                notFull.await();
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(Thread.currentThread().getName() + (++number));
        notFull.signalAll();
        lock.unlock();
    }

    public void desc() {
        lock.lock();
        try {
            while (number == 0) {
                notFull.await();
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(Thread.currentThread().getName() + (--number));
        notFull.signalAll();
        lock.unlock();
    }
}


/**
 * @auther zzyy
 * @create 2024-08-05 13:48
 * <p>
 * 两个线程，一个线程打印1-52，另一个打印字母A-Z打印顺序为12A34B...5152Z,
 * 要求用线程间通信
 * <p>
 * <p>
 * 有一个初始值为零的变量，现有两个线程对该变量操作，
 * 实现一个线程对变量加1，实现一个线程对变量减1,交替来10轮
 * <p>
 * <p>
 * 笔记：Java里面如何进行工程级别的多线程编写
 * * 1 多线程变成模板（套路）-----上
 * *     1.1  高内聚低耦合前提下，线程    操作    资源类
 * <p>
 * 2  判断/干活/通知
 * <p>
 * 3  一定要防止----虚假唤醒 //在多线程通信编码中，一定要防止----虚假唤醒，也不能出现虚假唤醒情况
 */
public class ProdConsumerDemo {
    public static void main(String[] args) {
        AirCondition airCondition = new AirCondition();
        new Thread(() -> {
            for (int i = 0; i <= 10; i++) {
                airCondition.add();
            }
        }, "A").start();

        new Thread(() -> {
            for (int i = 0; i <= 10; i++) {
                airCondition.desc();
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i <= 10; i++) {
                airCondition.add();
            }
        }, "C").start();

        new Thread(() -> {
            for (int i = 0; i <= 10; i++) {
                airCondition.desc();
            }
        }, "D").start();
    }
}





